package com.apestech.framework.sql.modul;

import com.apestech.framework.db.SqlSession;
import com.apestech.framework.dictionary.modul.Table;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.sql.SqlUtil;
import com.apestech.framework.sql.lib.DeleteSql;
import com.apestech.framework.sql.lib.InsertSql;
import com.apestech.framework.sql.lib.UpdateSql;

import java.util.ArrayList;

/**
 * @author hup
 * @create 2018-08-08-12:14
 */
public class FromList extends SqlUtil {

    private SqlSession session;
    private String from;
    private String sql;

    private ArrayList<From> tablist;
    private JSONObject aliasmap;
    private JSONObject tabmap;

    //表操作相关
    private String tabName;

    public FromList(String from, String sql, SqlSession session) throws Exception {
        this.session=session;
        this.from=from;
        this.sql=sql;
        this.tablist=null;
        this.aliasmap=new JSONObject();
        this.tabmap=new JSONObject();
        iniFrom();
    }

    private void iniFrom() throws Exception {
        tablist=null;
        if(from!=null && !"".equals(from.trim())) {
            tablist = getForm(from);
        } else {
            if(sql!=null){
                String s=sql.toUpperCase().trim();
                if(s.indexOf("INSERT")==0) {
                    InsertSql insert = new InsertSql(sql);
                    tablist = getForm(insert.getTableName());
                } else if(s.indexOf("UPDATE")==0){
                    UpdateSql update=new UpdateSql(sql);
                    tablist = getForm(update.getTableName());
                } else if(s.indexOf("DELETE")==0){
                    DeleteSql delete=new DeleteSql(sql);
                    tablist = getForm(delete.getTableName());
                } else {
                    SqlStru sqlStru=new SqlStru(sql);
                    tablist=sqlStru.getFrom();
                }
            }
        }
        if(tablist!=null){
            int len=tablist.size();
            for(int i=0; i<len; i++){
                aliasmap.put(tablist.get(i).getAlias(), tablist.get(i).getTab());
                Table table=getDictTable(tablist.get(i).getTab());
                if(table==null){
                    throw new Exception(getMessage("Table_errorTable","请输入数据库[({0})]中合法的表名[({1})]！", session.getDbName(), tablist.get(i).getTab()));
                }
            }
        } else {
            throw new Exception("请检查对应SQL的合法性！");
        }
    }

    public int size(){
        if(tablist==null) return 0;
        return tablist.size();
    }

    public String getTable(int i){
        return tablist.get(i).getTab();
    }

    public String getAlias(int i){
        return tablist.get(i).getAlias();
    }

    public String getTableFromAlias(String alias){
        return aliasmap.getString(alias);
    }

    public boolean hasTable(String tabName){
        if(tabName==null){
            return false;
        }
        boolean flag=false;
        for(SqlUtil.From f: tablist){
            if(tabName.equals(f.getTab())){
                flag=true;
                break;
            }
        }
        return flag;
    }

    public int getTableIndex(String tabName){
        int i=0;
        for(SqlUtil.From f: tablist){
            if(tabName.equals(f.getTab())){
                break;
            }
            i++;
        }
        return i;
    }

    public Table getDictTable(String tab) throws Exception {
        Object t=tabmap.get(tab);
        if(t==null){
            if(tab.toUpperCase().indexOf("SELECT")>=0){
                String str=getColumnSql(tab);
                tabmap.put(tab, session.getSqlTable(getNoWhereSql(str)));
            }
            else tabmap.put(tab, session.getDictTable(tab));
            t=tabmap.get(tab);
        }
        return (Table) t;
    }

    public Table getDictTableAll(String tab) throws Exception {
        if(tab.toUpperCase().indexOf("SELECT")>=0) return session.getSqlTable(tab);
        else return session.getDictTable(tab);
    }

    public String getDbType(){
        return session.getDbType();
    }

    public String getDbName(){
        return session.getDbName();
    }

    public String getTabName() {
          if(tablist!=null && tablist.size()==1){
            if(tabName!=null) return tabName;
            else return tablist.get(0).getTab();
        }
        return null;
    }

    public Table getTable() {
        if(tablist!=null && tablist.size()==1) return (Table) tabmap.get(tabmap.getFirstKey());
        return null;
    }

    public String getFrom() {
        return from;
    }

    public ArrayList<From> getTablist() {
        return tablist;
    }
}
